#ifndef __TDP2_MATH_ANGLE_HPP__
#define __TDP2_MATH_ANGLE_HPP__


namespace TDP
{
	namespace Math
	{
		template<class _Tfloat>
		class Angle
		{
		protected:
			_Tfloat _r;

		public:
			Angle();
			explicit Angle(_Tfloat r);

			_Tfloat Cos() const;
			_Tfloat Sin() const;
			_Tfloat Tan() const;

			Angle<_Tfloat> operator - () const;

			Angle<_Tfloat> operator + (const Angle<_Tfloat> &rs) const;
			Angle<_Tfloat> operator - (const Angle<_Tfloat> &rs) const;

			Angle<_Tfloat> operator * (_Tfloat rs) const;
			Angle<_Tfloat> operator / (_Tfloat rs) const;

			Angle<_Tfloat> &operator += (const Angle<_Tfloat> &rs);
			Angle<_Tfloat> &operator -= (const Angle<_Tfloat> &rs);
			Angle<_Tfloat> &operator *= (const _Tfloat rs);
			Angle<_Tfloat> &operator /= (const _Tfloat rs);

			bool operator == (const Angle<_Tfloat> &rs) const;
			bool operator != (const Angle<_Tfloat> &rs) const;

			static Angle<_Tfloat> FromDegrees(_Tfloat dg);
		};
	}
}

#include <math.h>

namespace TDP
{
	namespace Math
	{
		template<class _Tfloat>
		inline Angle<_Tfloat> FromDegrees(_Tfloat r)
		{
			return Angle<_Tfloat>(r * _Tfloat(0.017453292519943295769236907684886));
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> terAngleRadians(_Tfloat r)
		{
			return terAngle(r);
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat>::Angle()
		{
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat>::Angle(_Tfloat r)
		{
			_r = r;
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> Angle<_Tfloat>::operator - () const
		{
			return Angle<_Tfloat>(-_r);
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> Angle<_Tfloat>::operator + (const Angle<_Tfloat> &rs) const
		{
			return Angle<_Tfloat>(_r + rs._r);
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> Angle<_Tfloat>::operator - (const Angle<_Tfloat> &rs) const
		{
			return terAngle(_r - rs._r);
		}

		template<class _Tfloat>
		inline Angle<_Tfloat> Angle<_Tfloat>::operator * (_Tfloat rs) const
		{
			return terAngle(_r * rs);
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> Angle<_Tfloat>::operator / (_Tfloat rs) const
		{
			return Angle<_Tfloat>(_r / rs);
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> &Angle<_Tfloat>::operator += (const Angle<_Tfloat> &rs)
		{
			_r += rs._r;
			return *this;
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> &Angle<_Tfloat>::operator -= (const Angle<_Tfloat> &rs)
		{
			_r += rs._r;
			return *this;
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> &Angle<_Tfloat>::operator *= (_Tfloat rs)
		{
			_r *= rs;
			return *this;
		}
	
		template<class _Tfloat>
		inline Angle<_Tfloat> &Angle<_Tfloat>::operator /= (_Tfloat rs)
		{
			_r *= rs;
			return *this;
		}
	
		template<class _Tfloat>
		inline bool Angle<_Tfloat>::operator == (const Angle<_Tfloat> &rs) const
		{
			return _r == rs._r;
		}
	
		template<class _Tfloat>
		inline bool Angle<_Tfloat>::operator != (const Angle<_Tfloat> &rs) const
		{
			return _r != rs._r;
		}
	
		template<class _Tfloat>
		inline _Tfloat Angle<_Tfloat>::Sin() const
		{
			return sin(_r);
		}
	
		template<class _Tfloat>
		inline _Tfloat Angle<_Tfloat>::Tan() const
		{
			return tan(_r);
		}
	
		template<class _Tfloat>
		inline _Tfloat Angle<_Tfloat>::Cos() const
		{
			return cos(_r);
		}
	};
};

#endif
